/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.persistence.dao; // NOPMD

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import com.genia.toolbox.basics.bean.IterableIterator;
import com.genia.toolbox.persistence.bean.Persistable;
import com.genia.toolbox.persistence.bean.QueryParameters;
import com.genia.toolbox.persistence.criteria.Criteria;
import com.genia.toolbox.persistence.criteria.CriteriaResult;
import com.genia.toolbox.persistence.criteria.CriteriaType;
import com.genia.toolbox.persistence.criteria.PropertyField;
import com.genia.toolbox.persistence.criteria.criterion.Criterion;
import com.genia.toolbox.persistence.criteria.criterion.Junction;
import com.genia.toolbox.persistence.criteria.enumeration.MatchMode;
import com.genia.toolbox.persistence.criteria.field.Field;
import com.genia.toolbox.persistence.criteria.order.Order;
import com.genia.toolbox.persistence.exception.AggregateException;
import com.genia.toolbox.persistence.exception.PersistenceException;
import com.genia.toolbox.persistence.manager.CrossSessionManager;
import com.genia.toolbox.persistence.manager.FieldManager;
import com.genia.toolbox.persistence.manager.OrderManager;
import com.genia.toolbox.persistence.manager.PersistenceManager;
import com.genia.toolbox.persistence.manager.RestrictionsManager;

/**
 * a class that aggregates the methods of {@link PersistenceManager},
 * {@link OrderManager}, {@link FieldManager}, {@link RestrictionsManager} to
 * help using the persistence API.
 */
public abstract class AbstractDAO  // NOPMD
    implements PersistenceManager, OrderManager, FieldManager, RestrictionsManager
{

  /**
   * the persistenceManager to use.
   */
  private PersistenceManager persistenceManager;



  /**
   * Return a <code>Criterion</code> that always accept.
   * 
   * @return a <code>Criterion</code> that always accept
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#accept()
   */
  public Criterion accept()
  {
    return getRestrictionsManager().accept();
  }



  /**
   * Return a field that represents the addition of 2 fields.
   * 
   * @param field1
   *          the first field to be added
   * @param field2
   *          the second field to be added
   * @return a field representing <code>field1 + field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   */
  public Field addField(final Field field1, final Field field2)
      throws AggregateException
  {
    return getFieldManager().addField(field1, field2);
  }



  /**
   * Return a criterion that represents the conjunction of two criterion.
   * 
   * @param criterion1
   *          the first criterion
   * @param criterion2
   *          the seconde criterion
   * @return a criterion representation <code> criterion1 && criterion2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#and(com.genia.toolbox.persistence.criteria.criterion.Criterion,
   *      com.genia.toolbox.persistence.criteria.criterion.Criterion)
   */
  public Criterion and(final Criterion criterion1, final Criterion criterion2)
  {
    return getRestrictionsManager().and(criterion1, criterion2);
  }



  /**
   * return an Order describing an ascending sorting on the field given as
   * parameter.
   * 
   * @param field
   *          the field that will be sorted
   * @return an Order describing the sorting.
   * @see com.genia.toolbox.persistence.manager.OrderManager#asc(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Order asc(final Field field)
  {
    return getOrderManager().asc(field);
  }



  /**
   * Return a field that compute the average value of a numeric field in an
   * aggregate.
   * 
   * @param field
   *          the field to compute the average on
   * @return a field that compute the average value of a numeric field in an
   *         aggregate.
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#avg(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field avg(final Field field)
      throws AggregateException
  {
    return getFieldManager().avg(field);
  }



  /**
   * Return a field that represents the concatenation of 2 fields.
   * 
   * @param field1
   *          the first field to be concatened
   * @param field2
   *          the second field to be concatened
   * @return a field representing the concatenation of <code>field1</code> and
   *         <code>field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#concatField(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field concatField(final Field field1, final Field field2)
      throws AggregateException
  {
    return getFieldManager().concatField(field1, field2);
  }



  /**
   * Return a criterion that represents a conjunction.
   * 
   * @return a criterion that represents a conjunction
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#conjunction()
   */
  public Junction conjunction()
  {
    return getRestrictionsManager().conjunction();
  }



  /**
   * Return a field that count the number of aggregate line.
   * 
   * @return a field that count the number of aggregate line
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#count()
   */
  public Field count()
      throws AggregateException
  {
    return getFieldManager().count();
  }



  /**
   * This method deletes an object.
   * 
   * @param object
   *          The object to delete
   * @throws PersistenceException
   *           if any problems occur during persistence process
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#delete(com.genia.toolbox.persistence.bean.Persistable)
   */
  public void delete(final Persistable<? extends Serializable> object)
      throws PersistenceException
  {
    persistenceManager.delete(object);
  }



  /**
   * This method deletes an object if it is persistent, otherwise do nothing.
   * 
   * @param object
   *          The object to delete
   * @throws PersistenceException
   *           if any problems occur during persistence process *
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#deleteIfPersistent(com.genia.toolbox.persistence.bean.Persistable)
   */
  public void deleteIfPersistent(Persistable<? extends Serializable> object)
      throws PersistenceException
  {
    persistenceManager.deleteIfPersistent(object);
  }



  /**
   * Return a <code>Criterion</code> that always deny.
   * 
   * @return a <code>Criterion</code> that always deny
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#deny()
   */
  public Criterion deny()
  {
    return getRestrictionsManager().deny();
  }



  /**
   * return an Order describing an descending sorting on the field given as
   * parameter.
   * 
   * @param field
   *          the field that will be sorted
   * @return an Order describing the sorting.
   * @see com.genia.toolbox.persistence.manager.OrderManager#desc(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Order desc(final Field field)
  {
    return getOrderManager().desc(field);
  }



  /**
   * Return a criterion that represents a disjunction.
   * 
   * @return a criterion that represents a disjunction
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#disjunction()
   */
  public Junction disjunction()
  {
    return getRestrictionsManager().disjunction();
  }



  /**
   * Return a field that represents the division of 2 fields.
   * 
   * @param field1
   *          the first field to be divided
   * @param field2
   *          the second field to be divided
   * @return a field representing <code>field1 / field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#divField(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field divField(final Field field1, final Field field2)
      throws AggregateException
  {
    return getFieldManager().divField(field1, field2);
  }



  /**
   * This method return a {@link Field} that represents the elements of another
   * {@link Field} of type <code>Collection</code>. This Field can then be
   * used in isIn restrictions and such.
   * 
   * @param field
   *          the field to get the elements from
   * @return the field representing the elements of another {@link Field}
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#elements(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field elements(Field field)
      throws AggregateException
  {
    return getFieldManager().elements(field);
  }



  /**
   * Return a criterion that represents the equality between two fields. A
   * <code>null</code> field is never equal to any other field.
   * 
   * @param field1
   *          the first field in the equality
   * @param field2
   *          the second field in the equality
   * @return a criterion representing <code>field1.equals(field2)</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#equals(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion equals(final Field field1, final Field field2)
  {
    return getRestrictionsManager().equals(field1, field2);
  }



  /**
   * This method returns the results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @return the list of <code>CriteriaResult</code> that represents the
   *         result of the query
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#find(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> List<CriteriaResult<MAINTYPE>> find(final Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return persistenceManager.find(criteria);
  }



  /**
   * This method returns the results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @param parameters
   *          the parameters of this search
   * @return the list of <code>CriteriaResult</code> that represents the
   *         result of the query
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#find(com.genia.toolbox.persistence.criteria.Criteria,
   *      com.genia.toolbox.persistence.bean.QueryParameters)
   */
  public <MAINTYPE> List<CriteriaResult<MAINTYPE>> find(Criteria<MAINTYPE> criteria, QueryParameters parameters)
      throws PersistenceException
  {
    return persistenceManager.find(criteria, parameters);
  }



  /**
   * This method returns the unique result of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria.
   * @param criteria
   *          the criteria that describes the query
   * @return the <code>CriteriaResult</code> that represents the result of the
   *         query if there is an unique record, null if there is no record and throws a {@link ResultIsNotUniqueException} if there is more than one record
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#findUnique(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> CriteriaResult<MAINTYPE> findUnique(final Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return persistenceManager.findUnique(criteria);
  }



  /**
   * This method get an persited object given its class and identifier.
   * 
   * @param <IDENTIFIER>
   *          The type of the identifier
   * @param <TYPE>
   *          The type of the object to retrieve
   * @param type
   *          The class of the object to retrieve
   * @param identifier
   *          The identifier of the object to retrieve
   * @return the object of class <code>type</code> with the identifier
   *         <code>identifier</code> or <code>null</code> if no such object
   *         exists
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#get(java.lang.Class,
   *      java.io.Serializable)
   */
  public <IDENTIFIER extends Serializable, TYPE extends Persistable<IDENTIFIER>> TYPE get(final Class<TYPE> type, final IDENTIFIER identifier)
  {
    return persistenceManager.get(type, identifier);
  }



  /**
   * This methods return all the persisted objects of a given type.
   * 
   * @param <TYPE>
   *          the type of the objects to retrieve
   * @param type
   *          the class of the objects to retrieve
   * @return the list of all objects of the given type
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getAll(java.lang.Class)
   */
  public <TYPE> List<TYPE> getAll(final Class<TYPE> type)
      throws PersistenceException
  {
    return persistenceManager.getAll(type);
  }



  /**
   * Return a field that represents a constant.
   * 
   * @param value
   *          The value of this field
   * @return The field representing the value
   * @see com.genia.toolbox.persistence.manager.FieldManager#getConstantField(java.lang.Object)
   */
  public Field getConstantField(final Object value)
  {
    return getFieldManager().getConstantField(value);
  }



  /**
   * This methods return a new <code>Criteria</code> for the object of type
   * <code>mainType</code>.
   * 
   * @param <MAINTYPE>
   *          The main type of the criteria
   * @param mainType
   *          The class of the main type of the criteria
   * @return a <code>Criteria</code> to describe a new query
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getCriteria(java.lang.Class)
   */
  public <MAINTYPE> Criteria<MAINTYPE> getCriteria(final Class<MAINTYPE> mainType)
  {
    return persistenceManager.getCriteria(mainType);
  }



  /**
   * returns the {@link CrossSessionManager} to use with this
   * {@link PersistenceManager}.
   * 
   * @return the {@link CrossSessionManager} to use with this
   *         {@link PersistenceManager}
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getCrossSessionManager()
   */
  public CrossSessionManager getCrossSessionManager()
  {
    return getPersistenceManager().getCrossSessionManager();
  }



  /**
   * This method returns the <code>FieldManager</code> to use with this
   * persistent manager.
   * 
   * @return the <code>FieldManager</code> to use with this persistent manager
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getFieldManager()
   */
  public FieldManager getFieldManager()
  {
    return persistenceManager.getFieldManager();
  }



  /**
   * This method return a <code>Field</code> that represents the object
   * associated to the type passed in argument.
   * 
   * @param type
   *          the <code>CriteriaType</code> the resulting field must represent
   * @return the field representing the object of the type passed in argument
   * @see com.genia.toolbox.persistence.manager.FieldManager#getObjectField(com.genia.toolbox.persistence.criteria.CriteriaType)
   */
  public Field getObjectField(final CriteriaType<?> type)
  {
    return getFieldManager().getObjectField(type);
  }



  /**
   * This method returns the <code>OrderManager</code> to use with this
   * persistent manager.
   * 
   * @return the <code>OrderManager</code> to use with this persistent manager
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getOrderManager()
   */
  public OrderManager getOrderManager()
  {
    return persistenceManager.getOrderManager();
  }



  /**
   * getter for the persistenceManager property.
   * 
   * @return the persistenceManager
   */
  public PersistenceManager getPersistenceManager()
  {
    return persistenceManager;
  }



  /**
   * This method return a <code>Field</code> that represents a property of the
   * type passed in argument of a criteria.
   * 
   * @param type
   *          the type this field refers to
   * @param property
   *          the name of the property to represent
   * @return the field representing the property passed in argument
   * @see com.genia.toolbox.persistence.manager.FieldManager#getPropertyField(com.genia.toolbox.persistence.criteria.CriteriaType,
   *      java.lang.String)
   */
  public Field getPropertyField(final CriteriaType<?> type, final PropertyField<?, ?> property)
  {
    return getFieldManager().getPropertyField(type, property);
  }



  /**
   * This method return a <code>Field</code> that represents a property of the
   * main type of a criteria.
   * 
   * @param property
   *          the name of the property to represent
   * @return the field representing the property passed in argument
   * @see com.genia.toolbox.persistence.manager.FieldManager#getPropertyField(java.lang.String)
   */
  public Field getPropertyField(final PropertyField<?, ?> property)
  {
    return getFieldManager().getPropertyField(property);
  }



  /**
   * This method returns the <code>RestrictionsManager</code> to use with this
   * persistent manager.
   * 
   * @return the <code>RestrictionsManager</code> to use with this persistent
   *         manager
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#getRestrictionsManager()
   */
  public RestrictionsManager getRestrictionsManager()
  {
    return persistenceManager.getRestrictionsManager();
  }



  /**
   * Return a criterion that represents that a field is greater or equals to
   * another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 >= field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#greaterOrEquals(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion greaterOrEquals(final Field field1, final Field field2)
  {
    return getRestrictionsManager().greaterOrEquals(field1, field2);
  }



  /**
   * Return a criterion that represents that a field is greater than another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 > field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#greaterThan(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion greaterThan(final Field field1, final Field field2)
  {
    return getRestrictionsManager().greaterThan(field1, field2);
  }



  /**
   * Return a criterion that represents that a field match (without case)
   * another.
   * 
   * @param field1
   *          the first field in the matching
   * @param field2
   *          the second field in the matching
   * @param matchMode
   *          the type of match
   * @return a criterion representing that <code>field1</code> match (without
   *         case) <code>field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#ilike(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.enumeration.MatchMode)
   */
  public Criterion ilike(final Field field1, final Field field2, final MatchMode matchMode)
      throws AggregateException
  {
    return getRestrictionsManager().ilike(field1, field2, matchMode);
  }



  /**
   * Return a criterion that represents that a field is contained in a
   * collection of objects.
   * 
   * @param field
   *          the field to search
   * @param collection
   *          the collection the field must be in
   * @return a criterion representing that <code>field</code> is contained in
   *         <code>collection</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      java.util.Collection)
   */
  public Criterion isIn(final Field field, final Collection<?> collection)
  {
    return getRestrictionsManager().isIn(field, collection);
  }



  /**
   * Return a criterion that represents that a field is contained is the main
   * result of another query.
   * 
   * @param field
   *          the field to search
   * @param criteria
   *          the second query
   * @return a criterion representing that <code>field</code> is contained in
   *         the main result of <code>criteria</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.Criteria)
   */
  public Criterion isIn(final Field field, final Criteria<?> criteria)
  {
    return getRestrictionsManager().isIn(field, criteria);
  }



  /**
   * Return a criterion that represents that a field is contained in another
   * field (the second field must be a collection).
   * 
   * @param field1
   *          the field to search
   * @param field2
   *          the field to search in
   * @return a criterion representing that <code>field1</code> is contained in
   *         the field <code>field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion isIn(final Field field1, final Field field2)
  {
    return getRestrictionsManager().isIn(field1, field2);
  }



  /**
   * Return a criterion that represents that a field is not <code>null</code>.
   * 
   * @param field
   *          the field to check
   * @return a criterion that represents that a field is not <code>null</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isNotNull(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion isNotNull(final Field field)
  {
    return getRestrictionsManager().isNotNull(field);
  }



  /**
   * Return a criterion that represents that two fields are not the same. That
   * means that the two field are not equals and that the two fields are not
   * <code>null</code>.
   * 
   * @param field1
   *          the first field in the inequality
   * @param field2
   *          the second field in the inequality
   * @return a criterion representing <code>field1 != field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isNotSame(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion isNotSame(final Field field1, final Field field2)
  {
    return getRestrictionsManager().isNotSame(field1, field2);
  }



  /**
   * Return a criterion that represents that a field is <code>null</code>.
   * 
   * @param field
   *          the field to check
   * @return a criterion that represents that a field is <code>null</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isNull(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion isNull(final Field field)
  {
    return getRestrictionsManager().isNull(field);
  }



  /**
   * Return a criterion that represents that two fields are the same. That means
   * that either the two field are equals, or that the two fields are
   * <code>null</code>.
   * 
   * @param field1
   *          the first field in the equality
   * @param field2
   *          the second field in the equality
   * @return a criterion representing <code>field1 == field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#isSame(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion isSame(final Field field1, final Field field2)
  {
    return getRestrictionsManager().isSame(field1, field2);
  }



  /**
   * This method iterates over the results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @return the list of <code>CriteriaResult</code> that represents the
   *         result of the query
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#iterate(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> IterableIterator<CriteriaResult<MAINTYPE>> iterate(Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return getPersistenceManager().iterate(criteria);
  }



  /**
   * This method iterates over the results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @param parameters
   *          the parameters of this search
   * @return the list of <code>CriteriaResult</code> that represents the
   *         result of the query
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#iterate(com.genia.toolbox.persistence.criteria.Criteria,
   *      com.genia.toolbox.persistence.bean.QueryParameters)
   */
  public <MAINTYPE> IterableIterator<CriteriaResult<MAINTYPE>> iterate(Criteria<MAINTYPE> criteria, QueryParameters parameters)
      throws PersistenceException
  {
    return getPersistenceManager().iterate(criteria, parameters);
  }



  /**
   * Return a criterion that represents that a field is lesser or equals to
   * another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 <= field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#lesserOrEquals(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion lesserOrEquals(final Field field1, final Field field2)
  {
    return getRestrictionsManager().lesserOrEquals(field1, field2);
  }



  /**
   * Return a criterion that represents that a field is lesser than another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 < field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#lesserThan(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion lesserThan(final Field field1, final Field field2)
  {
    return getRestrictionsManager().lesserThan(field1, field2);
  }



  /**
   * Return a criterion that represents that a field match another.
   * 
   * @param field1
   *          the first field in the matching
   * @param field2
   *          the second field in the matching
   * @param matchMode
   *          the type of match
   * @return a criterion representing that <code>field1</code> match
   *         <code>field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#like(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.enumeration.MatchMode)
   */
  public Criterion like(final Field field1, final Field field2, final MatchMode matchMode)
      throws AggregateException
  {
    return getRestrictionsManager().like(field1, field2, matchMode);
  }



  /**
   * Return a field that represents the lower case representation of a field.
   * 
   * @param field
   *          the field to be converted
   * @return a field representing the lower case version of <code>field</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#lowerCase(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field lowerCase(final Field field)
      throws AggregateException
  {
    return getFieldManager().lowerCase(field);
  }



  /**
   * Return a field that compute the maximal value of a numeric field in an
   * aggregate.
   * 
   * @param field
   *          the field to compute the maximal on
   * @return a field that compute the maximal value of a numeric field in an
   *         aggregate.
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#max(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field max(final Field field)
      throws AggregateException
  {
    return getFieldManager().max(field);
  }



  /**
   * Return a field that compute the minimal value of a numeric field in an
   * aggregate.
   * 
   * @param field
   *          the field to compute the minimal on
   * @return a field that compute the minimal value of a numeric field in an
   *         aggregate.
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#min(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field min(final Field field)
      throws AggregateException
  {
    return getFieldManager().min(field);
  }



  /**
   * Return a field that represents the multiplication of 2 fields.
   * 
   * @param field1
   *          the first field to be multiplicated
   * @param field2
   *          the second field to be multiplicated
   * @return a field representing <code>field1 * field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#multField(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field multField(final Field field1, final Field field2)
      throws AggregateException
  {
    return getFieldManager().multField(field1, field2);
  }



  /**
   * Return a criterion that represents the negation of another criterion.
   * 
   * @param criterion
   *          the critertion to negate
   * @return a criterion representing the negation of <code>criterion</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#not(com.genia.toolbox.persistence.criteria.criterion.Criterion)
   */
  public Criterion not(final Criterion criterion)
  {
    return getRestrictionsManager().not(criterion);
  }



  /**
   * Return a criterion that represents the inequality between two fields. A
   * <code>null</code> field is never equal to any other field.
   * 
   * @param field1
   *          the first field in the inequality
   * @param field2
   *          the second field in the inequality
   * @return a criterion representing <code>!field1.equals(field2)</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#notEquals(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion notEquals(final Field field1, final Field field2)
  {
    return getRestrictionsManager().notEquals(field1, field2);
  }



  /**
   * Return a criterion that represents that a field is not contained in a
   * collection of objects.
   * 
   * @param field
   *          the field to search
   * @param collection
   *          the collection the field must not be in
   * @return a criterion representing that <code>field</code> is not contained
   *         in <code>collection</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#notIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      java.util.Collection)
   */
  public Criterion notIn(final Field field, final Collection<?> collection)
  {
    return getRestrictionsManager().notIn(field, collection);
  }



  /**
   * Return a criterion that represents that a field is not contained is the
   * main result of another query.
   * 
   * @param field
   *          the field to search
   * @param criteria
   *          the second query
   * @return a criterion representing that <code>field</code> is not contained
   *         in the main result of <code>criteria</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#notIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.Criteria)
   */
  public Criterion notIn(final Field field, final Criteria<?> criteria)
  {
    return getRestrictionsManager().notIn(field, criteria);
  }



  /**
   * Return a criterion that represents that a field is not contained in another
   * field (the second field must be a collection).
   * 
   * @param field1
   *          the field to search
   * @param field2
   *          the field to search in
   * @return a criterion representing that <code>field1</code> is not
   *         contained in the field <code>field2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#notIn(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Criterion notIn(final Field field1, final Field field2)
  {
    return getRestrictionsManager().notIn(field1, field2);
  }



  /**
   * Return a criterion that represents the disjunction of two criterion.
   * 
   * @param criterion1
   *          the first criterion
   * @param criterion2
   *          the seconde criterion
   * @return a criterion representation <code> criterion1 || criterion2</code>
   * @see com.genia.toolbox.persistence.manager.RestrictionsManager#or(com.genia.toolbox.persistence.criteria.criterion.Criterion,
   *      com.genia.toolbox.persistence.criteria.criterion.Criterion)
   */
  public Criterion or(final Criterion criterion1, final Criterion criterion2) // NOPMD
  {
    return getRestrictionsManager().or(criterion1, criterion2);
  }



  /**
   * This method saves a new object.
   * 
   * @param object
   *          The object to save
   * @throws PersistenceException
   *           if any problems occur during persistence process
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#save(com.genia.toolbox.persistence.bean.Persistable)
   */
  public void save(final Persistable<? extends Serializable> object)
      throws PersistenceException
  {
    persistenceManager.save(object);
  }



  /**
   * This method saves a new object or update an already persistent object. This
   * method should be avoided as much as possible. Finding if an object is
   * persistent or not is tedious and error prone, unexpected comportment can
   * arrise.
   * 
   * @param object
   *          The object to save or update
   * @throws PersistenceException
   *           if any problems occur during persistence process
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#saveOrUpdate(com.genia.toolbox.persistence.bean.Persistable)
   */
  public void saveOrUpdate(Persistable<? extends Serializable> object)
      throws PersistenceException
  {
    getPersistenceManager().saveOrUpdate(object);
  }



  /**
   * setter for the persistenceManager property.
   * 
   * @param persistenceManager
   *          the persistenceManager to set
   */
  public void setPersistenceManager(final PersistenceManager persistenceManager)
  {
    this.persistenceManager = persistenceManager;
  }



  /**
   * This method returns the main results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @return the list of result
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#simpleFind(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> List<MAINTYPE> simpleFind(final Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return persistenceManager.simpleFind(criteria);
  }



  /**
   * This method returns the main results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @param parameters
   *          the parameters of this search
   * @return the list of result
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#simpleFind(com.genia.toolbox.persistence.criteria.Criteria,
   *      com.genia.toolbox.persistence.bean.QueryParameters)
   */
  public <MAINTYPE> List<MAINTYPE> simpleFind(Criteria<MAINTYPE> criteria, QueryParameters parameters)
      throws PersistenceException
  {
    return persistenceManager.simpleFind(criteria, parameters);
  }



  /**
   * This method returns the unique main results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @return the unique result if there is an unique record, null if there is no record and throws a {@link ResultIsNotUniqueException} if there is more than one record
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#simpleFindUnique(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> MAINTYPE simpleFindUnique(final Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return persistenceManager.simpleFindUnique(criteria);
  }



  /**
   * This method iterates over the main results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @return the list of result
   * @throws PersistenceException
   *           when there is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#simpleIterate(com.genia.toolbox.persistence.criteria.Criteria)
   */
  public <MAINTYPE> IterableIterator<MAINTYPE> simpleIterate(Criteria<MAINTYPE> criteria)
      throws PersistenceException
  {
    return getPersistenceManager().simpleIterate(criteria);
  }



  /**
   * This method iterates over the main results of a criteria.
   * 
   * @param <MAINTYPE>
   *          the main type of the criteria
   * @param criteria
   *          the criteria that describes the query
   * @param parameters
   *          the parameters of this search
   * @return the list of result
   * @throws PersistenceException
   *           when the is a problem with the persisence layer
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#simpleIterate(com.genia.toolbox.persistence.criteria.Criteria,
   *      com.genia.toolbox.persistence.bean.QueryParameters)
   */
  public <MAINTYPE> IterableIterator<MAINTYPE> simpleIterate(Criteria<MAINTYPE> criteria, QueryParameters parameters)
      throws PersistenceException
  {
    return getPersistenceManager().simpleIterate(criteria, parameters);
  }



  /**
   * This method return a <code>Field</code> that represents the size of
   * another field that must be a collection.
   * 
   * @param field
   *          the field to inspect
   * @return the field representing the size of the {@link Field} given in
   *         parameter
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#size(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field size(Field field)
      throws AggregateException
  {
    return getFieldManager().size(field);
  }



  /**
   * Return a field that represents the substraction of 2 fields.
   * 
   * @param field1
   *          the first field to be subtsracted
   * @param field2
   *          the second field to be subtsracted
   * @return a field representing <code>field1 - field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#substractField(com.genia.toolbox.persistence.criteria.field.Field,
   *      com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field substractField(final Field field1, final Field field2)
      throws AggregateException
  {
    return getFieldManager().substractField(field1, field2);
  }



  /**
   * Return a field that compute the sum of a numeric field in an aggregate.
   * 
   * @param field
   *          the field to compute the sum on
   * @return a field that compute the sum of a numeric field in an aggregate.
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#sum(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field sum(final Field field)
      throws AggregateException
  {
    return getFieldManager().sum(field);
  }



  /**
   * This method updates an object.
   * 
   * @param object
   *          The object to update
   * @throws PersistenceException
   *           if any problems occur during persistence process
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#update(com.genia.toolbox.persistence.bean.Persistable)
   */
  public void update(final Persistable<? extends Serializable> object)
      throws PersistenceException
  {
    persistenceManager.update(object);
  }



  /**
   * Return a field that represents the upper case representation of a field.
   * 
   * @param field
   *          the field to be converted
   * @return a field representing the upper case version of <code>field</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   * @see com.genia.toolbox.persistence.manager.FieldManager#upperCase(com.genia.toolbox.persistence.criteria.field.Field)
   */
  public Field upperCase(final Field field)
      throws AggregateException
  {
    return getFieldManager().upperCase(field);
  }



  /**
   * flush eventual cached elements.
   * 
   * @see com.genia.toolbox.persistence.manager.PersistenceManager#clear()
   */
  public void clear()
  {
    persistenceManager.clear();
  }
}
